#ifndef __RIVATV_KCOMPAT_H
#define __RIVATV_KCOMPAT_H

#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
# include <linux/autoconf.h>
#else
# include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/videodev.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
# include <media/v4l2-dev.h>
#endif

#ifndef CONFIG_MODVERSIONS
# define _set_ver(x) x
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
# undef  _set_ver
# define _set_ver(x) x
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 5)
# undef video_register_device
# define video_register_device(a1,a2,a3) _set_ver(video_register_device)(a1,a2)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
# define MODULE_LICENSE(a) const char __module_license[] = "license=" a
#endif

/* if it is a RH ver and the version is on or above 2.4.20 */
/* use the 2.5.0 inputs and outputs */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
# undef remap_page_range
# define remap_page_range(a1,a2,a3,a4,a5) _set_ver(remap_pfn_range)(a1,a2,(a3)>>PAGE_SHIFT,a4,a5)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3) && !defined(RIVATV_ISREDHAT)
# undef remap_page_range
# define remap_page_range(a1,a2,a3,a4,a5) _set_ver(remap_page_range)(a2,a3,a4,a5)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20) && defined(RIVATV_ISREDHAT)
# undef remap_page_range
# define remap_page_range(a1,a2,a3,a4,a5) _set_ver(remap_page_range)(a2,a3,a4,a5)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
# define pci_set_dma_mask(a1,a2) !pci_dma_supported(a1,a2)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)
/* Converts a kernel virtual address returned by vmalloc_32() into the 
   a physical page. */
static inline struct page * vmalloc_to_page (void *address)
{
	pgd_t *pgd;  /* page directory entry */
	pmd_t *pmd;  /* page middle directory entry */
	pte_t *pte;  /* page table entries */
	ulong va = VMALLOC_VMADDR ((ulong) address);
	struct page *page = NULL;
	
	/* get the page directory for a linear kernel address */
	pgd = pgd_offset_k (va);

	/* page directory entry initialized ? */
	if (!pgd_none (*pgd)) {
		/* get the page middle directory */
		pmd = pmd_offset (pgd, va);
		/* entry already set ? */
		if (!pmd_none (*pmd)) {
			/* get a pointer to the page table entry */
			pte = pte_offset (pmd, va);
			/* any valid refering page in physical memory ? */
			if (pte_present (*pte)) {
				/* assign page return value */
				page = pte_page (*pte);
			}
		}
	}
	return page;
}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 24)

static inline void *video_get_drvdata(struct video_device *dev)
{
        return dev->priv;
}
static inline void video_set_drvdata(struct video_device *dev, void *data)
{
        dev->priv = data;
}

#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 54) && !defined (I2C_PEC)

static inline void i2c_adapter_inc_use (struct i2c_adapter *adap)
{
	MOD_INC_USE_COUNT;
}

static inline void i2c_adapter_dec_use (struct i2c_adapter *adap)
{
	MOD_DEC_USE_COUNT;
}

static inline void i2c_client_inc_use (struct i2c_client *client)
{
	MOD_INC_USE_COUNT;
}

static inline void i2c_client_dec_use (struct i2c_client *client)
{
	MOD_DEC_USE_COUNT;
}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 66)

static inline void *i2c_get_adapdata (struct i2c_adapter *adap)
{
	return adap->data;
}

static inline void i2c_set_adapdata (struct i2c_adapter *adap, void *data)
{
	adap->data = data;
}

static inline void *i2c_get_clientdata (struct i2c_client *client)
{
	return client->data;
}

static inline void i2c_set_clientdata (struct i2c_client *client, void *data)
{
	client->data = data;
}

static inline char *i2c_clientname (struct i2c_client *client)
{
        return client->name;
}

#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
static inline char *i2c_clientname (struct i2c_client *client)
{
        return client->name;
}
#endif


static inline int kcompat_i2c_client_get (struct i2c_client *client)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15)
	return 1;
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 54)
#ifndef I2C_PEC
	i2c_inc_use_client (client);
#endif /* !I2C_PEC */
	return 1;
#else
	return try_module_get (client->driver->owner);
#endif
}

static inline void kcompat_i2c_client_put (struct i2c_client *client)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 54)
#ifndef I2C_PEC
	i2c_dec_use_client (client);
#endif /* !I2C_PEC */
#else
	module_put (client->driver->owner);
#endif
#endif
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 66)
# define I2C_DEVNAME(str) .name = str
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
# define I2C_DEVNAME(str) .name = str
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
# define IRQ_RETVAL(x)
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 24)

static inline struct video_device * video_device_alloc (void)
{
	struct video_device *vfd;
        vfd = kmalloc(sizeof(*vfd),GFP_KERNEL);
        if (NULL == vfd)
                return NULL;
        memset(vfd,0,sizeof(*vfd));
        return vfd;
}

#endif

#if defined(CONFIG_GRKERNSEC_PAX) || defined(CONFIG_GRKERNSEC_PAX_RANDMMAP)
# define RIVATV_PAGE_SHARED PAGE_SHARED_NOEXEC
#else
# define RIVATV_PAGE_SHARED PAGE_SHARED
#endif

#ifndef __stringify
#define __stringify_1(x)	#x
#define __stringify(x)		__stringify_1(x)
#endif

#ifndef TUNER_PHILIPS_FQ1216ME
#define TUNER_PHILIPS_FQ1216ME	24
#endif

/* Extra I2C device id's. */
#ifndef I2C_DRIVERID_VPX32XX
#define I2C_DRIVERID_VPX32XX	42
#endif
#ifndef I2C_DRIVERID_SAA7108
#define I2C_DRIVERID_SAA7108	46
#endif
#ifndef I2C_DRIVERID_TW98
#define I2C_DRIVERID_TW98	0xF6
#endif
#ifndef I2C_DRIVERID_SAA7174
#define I2C_DRIVERID_SAA7174	0xF7
#endif
#ifndef I2C_DRIVERID_EXP3
#define I2C_DRIVERID_EXP3	0xF3
#endif

/* Quick and dirty hack for extra debugging commands in I2C drivers */
#define READ_REGISTERS		0xBF01
#define WRITE_REGISTERS		0xBF02
#define GET_NR_OF_REGISTERS	0xBF03
#define READ_REGISTER		0xBF04
#define WRITE_REGISTER		0xBF05

/* Extra PCI device id's. */
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR		0x0100
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR		0x0101
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_QUADRO
#define PCI_DEVICE_ID_NVIDIA_QUADRO			0x0103
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX		0x0110
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2		0x0111
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR		0x0113
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS		0x0150
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2		0x0151
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA		0x0152
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO		0x0153
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460		0x0170
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440		0x0171
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420		0x0172
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL		0x017C
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X		0x0181
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X	0x0182
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X		0x0183
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE3
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3			0x0200
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE3_1
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1			0x0201
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE3_2
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2			0x0202
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600		0x0250
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400		0x0251
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200		0x0253
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800		0x0280
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200_8X
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200_8X	0x0281
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 	0x0282
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA	0x0301
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800		0x0302
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA	0x0311
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600		0x0312
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600XT
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600XT		0x0314
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200		0x0320
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA	0x0321
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1		0x0322
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE		0x0323
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA	0x0330
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900		0x0331
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT		0x0332
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA	0x0333
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA	0x0341
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700		0x0342
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE		0x0344
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT		0x0140
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_6600
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600		0x0141
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT_1
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT_1		0x00F1
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_1
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_1		0x00F2
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX		0x0091
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT		0x0092
#endif

/* Extra PCI vendor id's. */
#ifndef PCI_VENDOR_ID_GAINWARD
#define PCI_VENDOR_ID_GAINWARD	0x10B0
#endif
#ifndef PCI_VENDOR_ID_MSI
#define PCI_VENDOR_ID_MSI	0x1462
#endif
#ifndef PCI_VENDOR_ID_AOPEN
#define PCI_VENDOR_ID_AOPEN	0xA0A0
#endif
#ifndef PCI_VENDOR_ID_PROLINK
#define PCI_VENDOR_ID_PROLINK	0x1554
#endif
#ifndef PCI_VENDOR_ID_VISIONTEK
#define PCI_VENDOR_ID_VISIONTEK	0x1545
#endif
#ifndef PCI_VENDOR_ID_GUILLEMOT
#define PCI_VENDOR_ID_GUILLEMOT 0x14AF
#endif
#ifndef PCI_VENDOR_ID_PINE
#define PCI_VENDOR_ID_PINE	0x1682
#endif
#ifndef PCI_VENDOR_ID_TRIPLEX
#define PCI_VENDOR_ID_TRIPLEX	0x10DE
#endif
#ifndef PCI_VENDOR_ID_ABIT
#define PCI_VENDOR_ID_ABIT	0x147B
#endif
#ifndef PCI_VENDOR_ID_DIAMOND
#define PCI_VENDOR_ID_DIAMOND	0x1092
#endif
#ifndef PCI_VENDOR_ID_EVGA
#define PCI_VENDOR_ID_EVGA	0x3842
#endif
#ifndef PCI_VENDOR_ID_GIGABYTE
#define PCI_VENDOR_ID_GIGABYTE	0x1458
#endif
#ifndef PCI_VENDOR_ID_SBS
#define PCI_VENDOR_ID_SBS	0x139C
#endif
#ifndef PCI_VENDOR_ID_LEADTEK
#define PCI_VENDOR_ID_LEADTEK	0x107D
#endif

#endif /* __RIVATV_KCOMPAT_H */

